package my.base.sql.impl;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

import my.base.sql.ConnectionPoolInter;

public class BaseConnectionPoolImpl implements ConnectionPoolInter {
	
	private int inUsed = 0; // 正在使用的连接数
	private Queue<Connection> availableConnections;
	private ArrayList<Connection> usedConnections;
	private int maxCon = 20;
	private String url;
	private String password;
	private String username;
	private String driver;
	
	public BaseConnectionPoolImpl(String url, String username, String password, String driver) {
		availableConnections = new LinkedList<Connection>();
        usedConnections = new ArrayList<Connection>();
        this.url = url;
		this.username = username;
		this.password = password;
		this.driver = driver;
	}

	public void setMaxCon(int max) {
		this.maxCon = max;
	}

	/**
	 *
	 * @return 如果达到最大连接数且不可用连接，返回null，其他的就返回正确的连接对象
	 */
	public synchronized Connection getConnection() {
		System.out.println("ConnectionPool.getConnection()");
        System.out.println("    Used connection:" + usedConnections.size());
        System.out.println("    Available connections: " + availableConnections.size());
        Connection con = null;
		if (availableConnections.size() >= 1) {
			con = availableConnections.poll();
			if (con != null) {
				this.inUsed++;
                this.usedConnections.add(con);
			}
		} else if (inUsed < maxCon) {
			con = newConnection();
		} else {
			// 无可用连接，切达到最大连接数
            con = null;
		}
        System.out.println("ConnectionPool.getConnection() over");
		return con;
	}

	public synchronized void freeConnection(Connection con) {
        System.out.println("ConnectionPool.freeConnection()");
		if (availableConnections.size() >= 10) {
			//allConnections.remove(con);
			try {
				con.close();
                this.usedConnections.remove(con);
				this.inUsed--;
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} else {
			this.availableConnections.add(con);
            this.usedConnections.remove(con);
			this.inUsed--;
		}
        System.out.println("ConnectionPool.freeConnection() over");
	}

	/**
	 * 当所有连接都可用时，释放所有连接，返回true，否则返回false
	 * @return 如果所有连接都可用，使用的连接
	 */
	public synchronized boolean release() {
		//if (inUsed == 0) {
			for (Connection con : usedConnections) {
				try {

					con.close();
					this.inUsed --;
				} catch (SQLException e) {
					e.printStackTrace();
                    return false;
				}
			}
			availableConnections.clear();
			return true;
//		} else {
//			return false;
//		}
	}

	/**
	 * 返回一个connection的对象
	 *
	 * @return
	 */
	private Connection newConnection() {
        System.out.println("ConnectionPool.newConnection");
		Connection connection = null;
		try {
			Class.forName(driver);
			connection = DriverManager.getConnection(url, username, password);
			this.inUsed++;
            this.usedConnections.add(connection);
			//this.allConnections.add(connection);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
        System.out.println("ConnectionPool.newConnection over");
		return connection;
	}

	public void test() {
		//System.out.println("allConnections size: " + allConnections.size());
		System.out.println("availableConnections size: "
				+ availableConnections.size());
        System.out.println("usedConnections size: " + usedConnections.size());
		System.out.println("inUsed: " + this.inUsed);
	}

}
